import 'package:context_menus/context_menus.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:o2oa_all_platform/common/extension/index.dart';

import '../../../../../common/api/x_message_assemble_communicate.dart';
import '../../../../../common/models/index.dart';
import '../../../../../common/style/color.dart';
import '../../../../../common/utils/index.dart';
import '../../../../../common/values/index.dart';
import '../../../../../common/widgets/index.dart';
import '../index.dart';
import 'chat_behavior.dart';
import 'received_msg.dart';
import 'send_msg.dart';

///
/// 消息列表
///
class ChatMsgListWidget extends GetView<ImChatController> {
  const ChatMsgListWidget({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Padding(
        padding: const EdgeInsets.only(right: 10.0, left: 10.0),
        child: Obx(() => ScrollConfiguration(
            behavior: const ChatScrollBehavior(),
            child: Align(
                alignment: Alignment.topCenter,
                child: ListView.separated(
                    padding: const EdgeInsets.only(bottom: 10),
                    reverse: true, // 反转
                    shrinkWrap: true,
                    controller: controller.msgListScrollController,
                    itemBuilder: (BuildContext context, int index) {
                      if (index == controller.state.msgList.length) {
                        return controller.state.hasMore
                            ? const Center(
                                child: SizedBox(
                                  height: 24,
                                  width: 24,
                                  child: CircularProgressIndicator(
                                    strokeWidth: 3,
                                  ),
                                ),
                              )
                            : O2UI.noResultView(context);
                      }
                      IMMessage info = controller.state.msgList[index];
                      return _msgItemView(context, info, index);
                    },
                    separatorBuilder: (context, index) {
                      return const SizedBox(height: 1);
                    },
                    itemCount: controller.state.msgList.length + 1)))));
  }

  Widget _msgItemView(BuildContext context, IMMessage info, int index) {
    return Obx(() => controller.state.isSelectMode
        ? _selectModeItemView(context, info, index)
        : _normalModeItemView(context, info, index));
  }

  Widget _selectModeItemView(BuildContext context, IMMessage info, int index) {
    return GestureDetector(
        onTap: () {
          controller.clickSelectMsgItem(info);
        },
        child: Row(
          crossAxisAlignment: CrossAxisAlignment.center,
          children: [
            controller.isMessageSelected(info)
                ? Icon(Icons.check_box_rounded,
                    size: 20, color: Theme.of(context).colorScheme.primary)
                : const Icon(Icons.check_box_outline_blank, size: 20),
            const SizedBox(width: 5),
            Expanded(
                child: info.createPerson ==
                        O2ApiManager.instance.o2User?.distinguishedName
                    ? sendListItemView(context, info, index)
                    : receivedLisItemView(context, info, index))
          ],
        ));
  }

  Widget _normalModeItemView(BuildContext context, IMMessage info, int index) {
    return GestureDetector(
        onTap: () {
          controller.clickMsgItem(info);
        },
        child: ContextMenuRegion(
          contextMenu:
              GenericContextMenu(buttonConfigs: _contextMenuListForItem(info)),
          child: info.createPerson ==
                  O2ApiManager.instance.o2User?.distinguishedName
              ? sendListItemView(context, info, index)
              : receivedLisItemView(context, info, index),
        ));
  }

  List<ContextMenuButtonConfig?> _contextMenuListForItem(IMMessage info) {
    List<ContextMenuButtonConfig?> list = [];
    if (info.toBody()?.type == IMMessageType.text.name) {
      list.add(ContextMenuButtonConfig('im_chat_menu_copy'.tr, onPressed: () {
        controller.copyTextMsg(info);
      }));
    }
    // 所有人的功能
    if (controller.state.imConfig.value?.enableForwardAndCollect() == true) {
      // 转发
      list.add(
          ContextMenuButtonConfig('im_chat_menu_forward'.tr, onPressed: () {
        controller.menuForwardMsg(info);
      }));
      // 收藏
      list.add(
          ContextMenuButtonConfig('im_chat_menu_collection'.tr, onPressed: () {
        controller.menuCollectionMsg(info);
      }));
      // 多选
      list.add(ContextMenuButtonConfig('im_chat_menu_multi_select'.tr,
          onPressed: () {
        controller.menuMultiSelect(info);
      }));
      // 引用
      list.add(ContextMenuButtonConfig('im_chat_menu_quote'.tr, onPressed: () {
        controller.menuAddQuoteMsg(info);
      }));
    }
    // 撤回消息
    if (controller.state.imConfig.value?.enableRevokeMsg == true) {
      final revokeOutMinute = controller.state.imConfig.value?.revokeOutMinute ?? 2; // 默认 2 分钟
      final time = DateTime.tryParse(info.createTime ?? "");
      final now = DateTime.now();
      if (time != null &&  (revokeOutMinute > 0 && now.difference(time).inMinutes < revokeOutMinute)) {
        // 时限内 可以撤回
        if (info.createPerson ==
            O2ApiManager.instance.o2User?.distinguishedName) {
          list.add(
              ContextMenuButtonConfig('im_chat_menu_revoke'.tr, onPressed: () {
            controller.revokeMsg(info);
          }));
        } else if (controller.conversationInfo?.type ==
                O2.imConversationTypeGroup &&
            controller.conversationInfo?.adminPerson ==
                O2ApiManager.instance.o2User?.distinguishedName) {
          list.add(ContextMenuButtonConfig('im_chat_menu_revoke_members'.tr,
              onPressed: () {
            controller.revokeMsg(info);
          }));
        }
      }
    }
    return list;
  }

  String _showPersonName(String? person) {
    if (person != null && person.isNotEmpty) {
      if (person.contains("@")) {
        return person.substring(0, person.indexOf("@"));
      }
      return person;
    }
    return "";
  }

  String _showTime(IMMessage info, int index) {
    var showTime = '';
    DateTime? time = DateTime.tryParse(info.createTime ?? "");
    if (time != null) {
      if (index == 0) {
        //第一条显示时间
        showTime = time.chatMsgShowTimeFormat();
      } else {
        IMMessage lastMsg = controller.state.msgList[index - 1];
        DateTime? lastTime = DateTime.tryParse(lastMsg.createTime ?? "");
        if (lastTime != null && lastTime.difference(time).inMinutes > 1) {
          // 超过一分钟 显示时间
          showTime = time.chatMsgShowTimeFormat();
        }
      }
    }
    return showTime;
  }

  // 接收到的消息格式
  Widget receivedLisItemView(BuildContext context, IMMessage info, int index) {
    var showTime = _showTime(info, index);
    return Column(
      children: [
        const SizedBox(height: 10),
        showTime.isEmpty
            ? Container()
            : Text(showTime, style: Theme.of(context).textTheme.bodySmall),
        Padding(
            padding: const EdgeInsets.only(right: 50.0, top: 5, bottom: 5),
            child: Row(
              mainAxisAlignment: MainAxisAlignment.start,
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                // 头像
                InkWell(
                    onTap: () =>
                        controller.clickAvatarToPerson(info.createPerson!),
                    child: SizedBox(
                      width: 50,
                      height: 50,
                      child: O2UI.personAvatar(info.createPerson!, 25),
                    )),
                Expanded(
                    flex: 1,
                    child: Column(
                      crossAxisAlignment: CrossAxisAlignment.start,
                      children: [
                        Padding(
                            padding: const EdgeInsets.only(left: 10),
                            child: Text(_showPersonName(info.createPerson),
                                style: Theme.of(context).textTheme.bodyLarge)),
                        const SizedBox(height: 5),
                        ReceivedMessageWidget(
                            msgBody: info.toBody()!, msgId: info.id!),
                        if (info.quoteMessage != null) _quoteMsgView(context, info.quoteMessage!, false),
                      ],
                    ))
              ],
            ))
      ],
    );
  }

  // 发送的消息格式
  Widget sendListItemView(BuildContext context, IMMessage info, int index) {
    var showTime = _showTime(info, index);
    return SizedBox(
        width: double.infinity,
        child: Column(
          children: [
            const SizedBox(height: 10),
            showTime.isEmpty
                ? Container()
                : Text(showTime, style: Theme.of(context).textTheme.bodySmall),
            Padding(
                padding: const EdgeInsets.only(left: 50, top: 5, bottom: 5),
                child: Row(
                  mainAxisAlignment: MainAxisAlignment.end,
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    Expanded(
                        flex: 1,
                        child: Column(
                          crossAxisAlignment: CrossAxisAlignment.end,
                          children: [
                            const SizedBox(height: 10),
                            SendMessageWidget(
                              msgBody: info.toBody()!,
                              msgId: info.id!,
                            ),
                            if (info.quoteMessage != null)
                              _quoteMsgView(context, info.quoteMessage!, true),
                          ],
                        )),
                    // 头像
                    InkWell(
                      onTap: () =>
                          controller.clickAvatarToPerson(info.createPerson!),
                      child: SizedBox(
                        width: 50,
                        height: 50,
                        child: O2UI.personAvatar(info.createPerson!, 25),
                      ),
                    )
                  ],
                ))
          ],
        ));
  }

  Widget _quoteMsgView(
      BuildContext context, IMMessage quoteMessage, bool isRight) {
    String text =
        '${quoteMessage.createPerson?.o2NameCut()}: ${quoteMessage.toBody()?.conversationBodyString()}';
    if (quoteMessage.toBody()?.type == 'image') {
      text = '${quoteMessage.createPerson?.o2NameCut()}: ';
    } else if (quoteMessage.toBody()?.type == 'location') {
      text += ' ${quoteMessage.toBody()?.address}';
    } else if (quoteMessage.toBody()?.type == 'file') {
      text += ' ${quoteMessage.toBody()?.fileName}';
    } else if (quoteMessage.toBody()?.type == 'audio') {
      text += ' ${quoteMessage.toBody()?.audioDuration ?? 0} "';
    }
    return Padding(
        padding: const EdgeInsets.only(top: 2),
        child: GestureDetector(
            onTap: () {
              controller.quoteMsgClick(quoteMessage);
            },
            child: Container(
              decoration: BoxDecoration(
                color: AppColor.imQuoteMsgColor,
                borderRadius: BorderRadius.circular(4),
              ),
              padding: const EdgeInsets.all(5),
             
              child: Row(
                  mainAxisAlignment:
                      isRight ? MainAxisAlignment.end : MainAxisAlignment.start,
                  mainAxisSize: MainAxisSize.min,
                  crossAxisAlignment: CrossAxisAlignment.center,
                  children: [
                    Container( 
                      constraints: const BoxConstraints(maxWidth: 200), 
                      child: Text(text, style: Theme.of(context).textTheme.bodySmall, maxLines: 3, overflow: TextOverflow.ellipsis)),
                    if (quoteMessage.toBody()?.type == 'image') _quoteMsgPictureBody(quoteMessage)
                  ]),
            )));
  }

  Widget _quoteMsgPictureBody(IMMessage quoteMessage) {
    var imageUrl = MessageCommunicationService.to
        .getIMMsgImageUrl(quoteMessage.toBody()!.fileId!);
    return Padding(
        padding: const EdgeInsets.only(left: 5),
        child: ClipRRect(
            borderRadius: BorderRadius.circular(4),
            child: Image.network(imageUrl,
                headers: controller.headers, width: 48, height: 48)));
  }
}
